package com.masonluo.mlonlinejudge.controller;

import com.masonluo.mlonlinejudge.entity.ExperimentProblemResult;
import com.masonluo.mlonlinejudge.mapper.ExperimentMapper;
import com.masonluo.mlonlinejudge.model.bo.ExperimentBo;
import com.masonluo.mlonlinejudge.model.dto.ExperimentUploadDto;
import com.masonluo.mlonlinejudge.model.param.ExperimentParam;
import com.masonluo.mlonlinejudge.model.param.ExperimentUploadParam;
import com.masonluo.mlonlinejudge.model.vo.ExperimentIdAndNameVo;
import com.masonluo.mlonlinejudge.model.vo.ExperimentScoreResultVo;
import com.masonluo.mlonlinejudge.model.vo.ExperimentVo;
import com.masonluo.mlonlinejudge.result.Result;
import com.masonluo.mlonlinejudge.result.ResultCode;
import com.masonluo.mlonlinejudge.service.ClassService;
import com.masonluo.mlonlinejudge.service.ExperimentResultService;
import com.masonluo.mlonlinejudge.service.ExperimentService;
import com.masonluo.mlonlinejudge.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;

/**
 * @program: mloj-backend
 * @description:
 * @author: LOTP
 * @create: 2021-10-06 01:39
 **/
@Api(description = "实验模块")
@RestController
@RequestMapping("/experiments")
public class ExperimentController {

    @Autowired
    private ExperimentService experimentService;

    @Autowired
    private ExperimentMapper experimentMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private ExperimentResultService experimentResultService;

    @Autowired
    private ClassService classService;

    @ApiOperation(value = "根据id查找实验")
    @GetMapping("/{experimentId}")
    public Result<ExperimentVo> findExperimentById(@PathVariable("experimentId") Integer experimentId) {
        if(Objects.isNull(experimentId)){
            throw new IllegalArgumentException("实验ID不可为空");
        }
        ExperimentVo experimentVo = experimentService.findById(experimentId);
        return Result.ok(experimentVo);
    }

    @ApiOperation(value = "所有实验")
    @GetMapping("/list")
    public Result list(@RequestParam("pageNum") Integer pageNum,
                       @RequestParam("pageSize") Integer pageSize,
                       @RequestParam(value = "status",required = false) String status,
                       @RequestParam(value = "userId",required = false) Integer userId){

        return new Result(ResultCode.OK,"实验信息查找成功",experimentService.list(pageNum, pageSize, userId, status),pageNum,pageSize, experimentService.countByUserId(userId,status));

    }

    @ApiOperation(value = "根据学校Id获取实验的id和名称")
    @GetMapping("/listBySchoolIdAndStatus")
    public Result listExperimentIdAndNameBySchoolIdAndStatus(
                        @RequestParam(value = "status",required = false) String status,
                        @RequestParam(value = "schoolId") Integer schoolId){
        List<ExperimentIdAndNameVo> experimentIdAndName = experimentService.findExperimentIdAndNameBySchoolIdAndStatus(schoolId, status);
        return new Result(ResultCode.OK,"实验信息查找成功",experimentIdAndName);

    }

    @ApiOperation(value = "根据实验id和用户id查找实验")
    @GetMapping("/listByExperimentIdAndUserId")
    public Result<ExperimentVo> findByExperimentIdAndUserId(@RequestParam("experimentId") Integer experimentId,
                                                            @RequestParam("userId") Integer userId) {
        if(Objects.isNull(experimentId)){
            throw new IllegalArgumentException("实验ID不可为空");
        }
        ExperimentBo experimentBo = experimentService.findByExperimentIdAndUserId(experimentId,userId);
        return new Result(ResultCode.OK,"实验信息查找成功",experimentBo);
    }


    @ApiOperation(value = "根据实验Id删除实验信息")
    @DeleteMapping("/{experimentId}")
    @SuppressWarnings("rawtypes")
    public Result<Boolean> delete(@PathVariable("experimentId") Integer experimentId,
                                  @RequestParam("userId") Integer userId) {
        if(Objects.isNull(experimentId)){
            throw new IllegalArgumentException("实验ID不可为空");
        }
        Boolean delete = experimentService.delete(experimentId, userId);
        return Result.ok();

    }

    @ApiOperation(value = "管理员通过实验Id修改实验信息")
    @PatchMapping("/admin/updateExperimentById")
    public Result updateExperimentById(@RequestParam("userId") Integer userId,
                                       @RequestBody ExperimentParam experimentParam) {
        if(Objects.isNull(experimentParam) || Objects.isNull(userId)){
            throw new IllegalArgumentException("实验数据不可为空");
        }
        return Result.ok(experimentService.updateExperimentById(userId,experimentParam));
    }



    @ApiOperation(value = "创建实验")
    @PostMapping("/add")
    public Result<ExperimentVo> add(@RequestBody @Valid ExperimentUploadParam experimentUploadParam) {
        if(Objects.isNull(experimentUploadParam)){
            throw new IllegalArgumentException("实验数据不可为空");
        }
        return Result.ok(experimentService.addExperiment(experimentUploadParam));
    }

    @ApiOperation(value = "管理员创建实验")
    @PostMapping("/admin/add")
    public Result<ExperimentBo> adminAdd(@RequestParam("userId") Integer userId,
                                         @RequestBody @Valid ExperimentUploadDto experimentUploadDto) {
        if(Objects.isNull(experimentUploadDto) || Objects.isNull(userId)){
            throw new IllegalArgumentException("实验数据不可为空");
        }
        return Result.ok(experimentService.addExperiment(userId, experimentUploadDto));
    }

    /*@ApiOperation(value = "根据学校Id返回实验列表(分页)")
    @GetMapping
    public Result findExperimentBySchoolId(@RequestParam("schoolId") Integer schoolId,
                                           @RequestParam(value = "status",required = false) String status,
                                           @RequestParam("pageNum") Integer pageNum,
                                           @RequestParam("pageSize") Integer pageSize) {
        if(Objects.isNull(schoolId)){
            throw new IllegalArgumentException("学校ID不可为空");
        }
        List<ExperimentBo> experiments = experimentService.listBySchoolId(schoolId,status, pageNum, pageSize);
        return new Result(ResultCode.OK,"实验信息查找成功",experiments,pageNum,pageSize,experimentService.countBySchoolId(schoolId,status));

    }*/

    @ApiOperation(value = "根据班级id获取班级参与的实验")
    @GetMapping("/listBySchoolIdAndClassId")
    public Result listByClassIdAndSchoolId(@RequestParam(value = "classId",required = false) Integer classId,
                                           @RequestParam("schoolId") Integer schoolId,
                                           @RequestParam(value = "status",required = false) String status,
                                           @RequestParam("pageNum") Integer pageNum,
                                           @RequestParam("pageSize") Integer pageSize) {
        if(Objects.isNull(schoolId)){
            throw new IllegalArgumentException("学校ID不可为空");
        }

        List<ExperimentBo> experiments = experimentService.listByClassId(classId, schoolId, status, pageNum, pageSize);
        return new Result(ResultCode.OK,"实验信息查找成功",experiments,pageNum,pageSize,experimentService.countBySchoolId(schoolId,status));

    }

    @ApiOperation(value = "管理员设置实验状态")
    @GetMapping("/admin/setExperimentStatus")
    public Result<Boolean> adminsetStatus(@RequestParam("experimentId") Integer experimentId,
                                          @RequestParam("schoolId") Integer schoolId,
                                          @RequestParam(value = "status",required = false) String status) {
        if(Objects.isNull(experimentId) || Objects.isNull(experimentId) || (Objects.isNull(status))){
            throw new IllegalArgumentException("实验ID/学校ID/实验状态不可为空");
        }
        if (!"ENABLE".equals(status) && !"DISABLE".equals(status)){
            throw new IllegalArgumentException("请输入正确的实验状态：ENABLE / DISABLE");
        }
        return Result.ok(experimentService.setExperimentStatus(experimentId,schoolId,status));
    }

    @ApiOperation(value = "管理员设置实验时间")
    @GetMapping("/admin/setExperimentDateTime")
    public Result<Boolean> adminsetTime(@RequestParam("experimentId") Integer experimentId,
                                          @RequestParam("schoolId") Integer schoolId,
                                          @RequestParam("startTime") String startTime,
                                        @RequestParam("endTime") String endTime) {
        if(Objects.isNull(experimentId) || Objects.isNull(experimentId) || Objects.isNull(startTime) || Objects.isNull(endTime)){
            throw new IllegalArgumentException("实验ID/学校ID/实验时间不可为空");
        }
        return Result.ok(experimentService.setExperimentTime(experimentId,schoolId,startTime,endTime));
    }

    @ApiOperation(value = "学校关联实验")
    @GetMapping("/admin/relatedSchool")
    public Result<Boolean> doExperimentRelatedSchool(@RequestParam("experimentId") Integer experimentId,
                                        @RequestParam("schoolId") Integer schoolId) {
        if(Objects.isNull(experimentId) || Objects.isNull(experimentId)){
            throw new IllegalArgumentException("实验ID/学校ID不可为空");
        }
        return Result.ok(experimentService.doExperimentRelatedSchool(experimentId,schoolId));
    }

    @ApiOperation(value = "校管理员其学校未关联的实验列表")
    @GetMapping("/admin/findNotRelatedSchool")
    public Result<List<ExperimentVo>> findNotRelatedSchool(@RequestParam("userId") Integer userId,
                                                           @RequestParam("pageNum")Integer pageNum,
                                                           @RequestParam("pageSize") Integer pageSize     ) {
        if(Objects.isNull(userId)){
            throw new IllegalArgumentException("管理员Id不可为空");
        }
        return new Result(ResultCode.OK, "查找成功",experimentService.findNotRelatedSchool(userId,pageNum,pageSize),pageNum,pageSize,experimentService.countNotRelatedSchool(userId));
    }

    @ApiOperation(value = "根据实验ID与学校ID修改该题目的分类")
    @GetMapping("/admin/updateProblemCategory")
    public Result<Boolean> updateProblemCategory(@RequestParam("experimentId") Integer experimentId,
                                                 @RequestParam("schoolId") Integer schoolId,
                                                 @RequestParam("problemId") Integer problemId) {
        if(Objects.isNull(experimentId) || Objects.isNull(schoolId) || Objects.isNull(problemId)){
            throw new IllegalArgumentException("实验ID/学校ID/题目ID不可为空");
        }
        return Result.ok(experimentService.updateProblemCategory(experimentId,schoolId,problemId));
    }

    /*@ApiOperation("根据实验id和班级id返回学生实验成绩")
    @PostMapping("findByExperimentAndClass")
    public Result<List<ExperimentresultScoreDto>> findByExamAndExperiment(@RequestBody ExperimentResultParam experimentResultParam){
        List<ExperimentresultScoreDto> experimentresultScoreDtos = experimentResultService.findByExperimentAndClass(experimentResultParam);
        Integer total = experimentResultService.getTotalStudent(experimentResultParam);
        return new Result(ResultCode.OK,"信息查找成功",experimentresultScoreDtos,experimentResultParam.getCurrent(),experimentResultParam.getLimit(),total);
    }*/

   /* @ApiOperation("根据班级id返回学生实验成绩表")
    @PostMapping("findByExperimentAndClass")
    public Result<List<ExperimentresultScoreDto>> findByClassId(@RequestParam("teacherId")Integer teacherId,
                                                                @RequestParam("classId")Integer classId,
                                                                @RequestParam("pageNum") Integer pageNum,
                                                                @RequestParam("pageSize") Integer pageSize){
        List<ExperimentScoreDto> experimentScoreDtos = experimentResultService.findByClassId(teacherId,classId,pageNum,pageSize);
        return new Result(ResultCode.OK,"信息查找成功",experimentScoreDtos,pageNum,pageSize,experimentScoreDtos.size());
    }*/

    @ApiOperation("根据班级id返回学生实验成绩表")
    @PostMapping("findScoreByTeacherIdAndClassId")
    public Result<List<ExperimentScoreResultVo>> findScoreByTeacherIdAndClassId(@RequestParam("teacherId")Integer teacherId,
                                                                                @RequestParam("classId")Integer classId,
                                                                                @RequestParam("pageNum") Integer pageNum,
                                                                                @RequestParam("pageSize") Integer pageSize){
        List<ExperimentScoreResultVo> experimentScoreResultVos = experimentResultService.findScoreByTeacherIdAndClassId(teacherId,classId,pageNum,pageSize);
        return new Result(ResultCode.OK,"信息查找成功",experimentScoreResultVos,pageNum,pageSize,classService.getTotalStudentByClassId(teacherId, classId));
    }

    @ApiOperation("根据班级id刷新学生实验成绩表")
    @PostMapping("refreshScoreByTeacherIdAndClassId")
    public Result<List<ExperimentScoreResultVo>> refreshScoreByTeacherIdAndClassId(@RequestParam("teacherId")Integer teacherId,
                                                                                 @RequestParam("classId")Integer classId,
                                                                                 @RequestParam("pageNum") Integer pageNum,
                                                                                 @RequestParam("pageSize") Integer pageSize){
        List<ExperimentScoreResultVo> experimentScoreResultVos = experimentResultService.refreshScoreByTeacherIdAndClassId(teacherId,classId,pageNum,pageSize);
        return new Result(ResultCode.OK,"信息查找成功",experimentScoreResultVos,pageNum,pageSize,classService.getTotalStudentByClassId(teacherId, classId));
    }

    @ApiOperation("根据班级id重构学生实验成绩表")
    @PostMapping("rebuildScoreByTeacherIdAndClassId")
    public Result<List<ExperimentScoreResultVo>> rebuildScoreByTeacherIdAndClassId(@RequestParam("teacherId")Integer teacherId,
                                                                                   @RequestParam("classId")Integer classId){
        List<ExperimentScoreResultVo> experimentScoreResultVos = experimentResultService.bulidScoreByTeacherIdAndClassId(teacherId,classId);
        return new Result(ResultCode.OK,"信息查找成功",experimentScoreResultVos);
    }

    @ApiOperation("根据用户id和实验id返回学生实验题目成绩")
    @PostMapping("findExperimentProblemResult")
    public Result<List<ExperimentProblemResult>> findExperimentProblemResult(@RequestParam("userId")Integer userId,
                                                                                @RequestParam("experimentId")Integer experimentId){
        List<ExperimentProblemResult> experimentProblemResult = experimentResultService.findExperimentProblemResult(userId, experimentId);
        return new Result(ResultCode.OK,"信息查找成功",experimentProblemResult);
    }


    @ApiOperation("根据学校Id重新排序实验")
    @PostMapping("sortExperiment")
    public Result<Boolean> sortExperimentByIdsAndSchoolId(@RequestParam("schoolId")Integer schoolId,
                                                          @RequestBody List<Integer> experimentIds){
        boolean sort = experimentService.sortExperimentByIdsAndSchoolId(experimentIds, schoolId);
        return new Result(ResultCode.OK,"重新排序成功",sort);
    }



}


